package com.ninong.ker.admin.service.impl;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ninong.ker.admin.service.RoleService;
import com.ninong.ker.common.auth.SecurityAdmin;
import com.ninong.ker.common.user.OnlineUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ninong.ker.admin.domain.Role;
import com.ninong.ker.admin.domain.RoleMenu;
import com.ninong.ker.admin.domain.UserRole;
import com.ninong.ker.admin.mapper.RoleMapper;
import com.ninong.ker.admin.mapper.RoleMenuMapper;
import com.ninong.ker.admin.mapper.UserRoleMapper;
import com.ninong.ker.admin.service.dto.RoleDTO;
import com.ninong.ker.common.exception.CmdException;
import com.ninong.ker.common.tools.Constants;
import com.ninong.ker.common.tools.enums.BusinessEnum;

/**
 * @author cmd
 * @date 2020年11月29日 上午11:12:45
 */
@Service
@org.apache.dubbo.config.annotation.Service(version = "1.0.0")
@Transactional(rollbackFor = RuntimeException.class)
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private UserRoleMapper userRoleMapper;
    @Autowired
    private RoleMenuMapper roleMenuMapper;
    @Autowired
    private SecurityAdmin securityAdmin;

    @Override
    public PageInfo<Role> listPage(RoleDTO dto) {
        PageHelper.startPage(dto.getCurrentPage(), dto.getPageSize());
        OnlineUser onlineUser = securityAdmin.currentUser();
        LambdaQueryWrapper<Role> query = new LambdaQueryWrapper<>();
        if (StringUtils.isEmpty(onlineUser.getTenantId())) {
            query.eq(Role::getTenantId, "");
        }
        if (!StringUtils.isEmpty(dto.getName())) {
            query.like(Role::getName, dto.getName());
        }
        List<Role> roles = baseMapper.selectList(query);
        return new PageInfo<Role>(roles);
    }

    @Override
    public void delete(String[] ids) {
        List<String> idList = Arrays.asList(ids);
        idList.forEach(id -> {
            Integer count = userRoleMapper.selectCount(new LambdaQueryWrapper<UserRole>().eq(UserRole::getRoleId, id));
            if (count > Constants.ZERO) {
                throw new CmdException(BusinessEnum.ROLE_USER_EXIST);
            }
            count = roleMenuMapper.selectCount(new LambdaQueryWrapper<RoleMenu>().eq(RoleMenu::getRoleId, id));
            if (count > Constants.ZERO) {
                throw new CmdException(BusinessEnum.ROLE_MENU_EXIST);
            }
        });
        baseMapper.deleteBatchIds(idList);
    }

    @Override
    public void create(Role entity) {
        Integer count = null;
        if (StringUtils.isEmpty(entity.getId())) {
            count = baseMapper.selectCount(new LambdaQueryWrapper<Role>().eq(Role::getName, entity.getName()));
            if (count > Constants.ZERO) {
                throw new CmdException(BusinessEnum.ROLE_NAME_REPEAT);
            }
        } else {
            count = baseMapper
                    .selectCount(new LambdaQueryWrapper<Role>().ne(Role::getId, entity.getId()).eq(Role::getName, entity.getName()));
            if (count > Constants.ZERO) {
                throw new CmdException(BusinessEnum.ROLE_NAME_REPEAT);
            }

        }
        OnlineUser onlineUser = securityAdmin.currentUser();
        entity.setTenantId(onlineUser.getTenantId());
        saveOrUpdate(entity);
    }

    @Override
    public Role get(String id) {
        Role entity = baseMapper.selectById(id);
        return entity;
    }

    @Override
    public List<Role> listRoleTree() {
        LambdaQueryWrapper<Role> query = new LambdaQueryWrapper<>();OnlineUser onlineUser = securityAdmin.currentUser();
        if (StringUtils.isEmpty(onlineUser.getTenantId())) {
            query.eq(Role::getTenantId,"");
        }
        return baseMapper.selectList(query);
    }

    @Override
    public List<String> listTreeByUserId(String userId) {
        LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserRole::getUserId, userId);
        List<UserRole> list = userRoleMapper.selectList(queryWrapper);
        List<String> checkedIds = list.stream().map(UserRole::getRoleId).collect(Collectors.toList());
        return checkedIds;
    }

    @Override
    public void merge(String userId, List<String> roleIds) {
        LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
        OnlineUser onlineUser = securityAdmin.currentUser();
        queryWrapper.eq(UserRole::getUserId, userId);
        queryWrapper.eq(UserRole::getTenantId, onlineUser.getTenantId());
        userRoleMapper.delete(queryWrapper);
        roleIds.forEach(id -> {
            UserRole entity = new UserRole(userId, id, onlineUser.getTenantId());
            userRoleMapper.insert(entity);
        });
    }

}
